using System.Collections.Generic;
using UnityEngine;

public class Level : MonoBehaviour
{
	public class Settings
	{
		private float maxFireCurve = 0;

		private int landDetectorVersion = 0;

		private bool fixShockRecoveryBug = false;

		private int failureVersion = 0;

		private bool headIsLethal = false;

		private int controlVersion = 0;

		private float hpMultiplier = 1.0f;

		private int targetingVersion = 0;

		public float MaxFireCurve
		{
			get
			{
				return maxFireCurve;
			}
		}

		public int LandDetectorVersion
		{
			get
			{
				return landDetectorVersion;
			}
		}

		public bool FixShockRecoveryBug
		{
			get
			{
				return fixShockRecoveryBug;
			}
		}

		public int FailureVersion
		{
			get
			{
				return failureVersion;
			}
		}

		public int ControlVersion
		{
			get
			{
				return controlVersion;
			}
		}

		public bool HeadIsLethal
		{
			get
			{
				return headIsLethal;
			}
		}

		public float HpMultiplier
		{
			get
			{
				return hpMultiplier;
			}
		}

		public int TargetingVersion
		{
			get
			{
				return targetingVersion;
			}
		}

		public Settings(float maxFireCurve, int landDetectorVersion, bool fixShockRecoveryBug, int failureVersion, bool headIsLethal, int controlVersion, float hpMultiplier, int targetingVersion)
		{
			this.maxFireCurve = maxFireCurve;
			this.landDetectorVersion = landDetectorVersion;
			this.fixShockRecoveryBug = fixShockRecoveryBug;
			this.failureVersion = failureVersion;
			this.headIsLethal = headIsLethal;
			this.controlVersion = controlVersion;
			this.hpMultiplier = hpMultiplier;
			this.targetingVersion = targetingVersion;
		}

		public Settings(Settings src, int landDetectorVersionOverride)
		{
			this.maxFireCurve = src.maxFireCurve;
			this.landDetectorVersion = landDetectorVersionOverride;  // Use the override value
			this.fixShockRecoveryBug = src.fixShockRecoveryBug;
			this.failureVersion = src.failureVersion;
			this.headIsLethal = src.headIsLethal;
			this.controlVersion = src.controlVersion;
			this.hpMultiplier = src.hpMultiplier;
			this.targetingVersion = src.targetingVersion;
		}
	}

	[SerializeField]
	private int landDetectorOverride;

	[SerializeField]
	private float shadowDistanceOverride;

	private Main main;
	private IEnemy[] enemies;

	private Unbreakable[] unbreakables;
	private Settings settings;

	private List<CannonBall> cannonBalls;
	public bool Cleared { get; private set; }

	public Player Player { get; private set; }

	public float ShadowDistanceOverride => 0f;

	public void ManualStart(Main main, Player.Settings playerSettings, BulletBase bulletPrefab, Settings levelSettings, Dictionary<string, Material> materialSet)
	{
		this.main = main;
		enemies = GameObject.FindObjectsOfType<Enemy>();
		foreach (Enemy enemy in enemies)
		{
			enemy.ManualStart(this, materialSet);
		}
		settings = levelSettings;
		Player = GameObject.FindObjectOfType<Player>();
		Player.ManualStart(playerSettings, levelSettings, bulletPrefab, materialSet);
	}

	public void ManualFixedUpdate(float deltaTime, bool pointerDown, Vector2 pointer)
	{
		foreach (Enemy enemy in enemies)
		{
			enemy.ManualFixedUpdate(deltaTime, Player.HeadPosition, pointerDown);
		}
		if (Player != null)
		{
			Player.ManualFixedUpdate(deltaTime, pointerDown, pointer);
		}
	}

	public void ManualUpdate(float deltaTime)
	{
		if (AnyEnemyAlive())
		{
			foreach (Enemy enemy in enemies)
			{
				enemy.ManualUpdate(deltaTime);
			}
		}
		else
		{
			Main.Instance.gameStatus = GameStatus.GameComplete;
		}
		if (Player.Alive)
		{
			Player.ManualUpdate(deltaTime);
		}
	}

	public bool AnyEnemyAlive()
	{
		if (enemies == null || enemies.Length == 0)
		{
			return false;
		}
		else
		{
			for (int i = 0; i < enemies.Length; i++)
			{
				if (enemies[i].Alive)
				{
					return true;
				}
			}
		}
		return false;
	}

	public void ForceClear()
	{
		if (enemies == null || enemies.Length == 0)
		{
			return;
		}
		else
		{
			for (int i = 0; i < enemies.Length; i++)
			{
				if (enemies[i].Alive)
				{
					enemies[i].ForceClear();
				}
			}
		}
	}
	public void ResetForce()
	{
		if (enemies == null || enemies.Length == 0)
		{
			return;
		}
		else
		{
			for (int i = 0; i < enemies.Length; i++)
			{
				if (enemies[i].Alive)
				{
					enemies[i].ResetForce();
				}
			}
		}
	}
	public void CollectEnemyPartPoints(List<Vector3> points)
	{
		if (points == null) return;

		foreach (IEnemy enemy in enemies)
		{
			// 假设每个敌人实现了GetPartPoints方法返回部件位置列表
			//points.AddRange(enemy.GetPartPoints());
		}
	}

	public IEnemyObject FindNearestEnemy(out float distance, Vector3 point)
	{
		distance = float.MaxValue;
		IEnemyObject nearestEnemy = null;

		foreach (IEnemy enemy in enemies)
		{
			if (!enemy.Alive) continue;

			float dist = Vector3.Distance(enemy.Position, point);
			if (dist < distance)
			{
				distance = dist;
				nearestEnemy = enemy;
			}
		}
		return nearestEnemy;
	}

	public float CalcNearestEnemyDistance(Vector3 point, bool subtractApproxRadius)
	{
		float minDistance = float.MaxValue;

		foreach (IEnemy enemy in enemies)
		{
			if (!enemy.Alive) continue;

			float dist = Vector3.Distance(enemy.Position, point);
			if (subtractApproxRadius)
			{
				dist -= enemy.ApproxRadius;
				if (dist < 0) dist = 0;
			}

			if (dist < minDistance)
			{
				minDistance = dist;
			}
		}

		return minDistance == float.MaxValue ? 0f : minDistance;
	}

	public Vector3 CalcEnemyCenterDirection(Vector3 cameraPosition, Quaternion cameraRotation, bool includeDeadPlayer)
	{
		Vector3 center = Vector3.zero;
		int count = 0;

		// 收集所有存活的敌人位置
		foreach (IEnemy enemy in enemies)
		{
			if (enemy.Alive)
			{
				center += enemy.Position;
				count++;
			}
		}

		// 如果需要包括死亡玩家且玩家存在
		if (includeDeadPlayer && Player != null && !Player.Alive)
		{
			center += Player.transform.position;
			count++;
		}

		if (count == 0)
			return Vector3.forward; // 默认返回相机前方方向

		center /= count; // 计算平均位置
		return (center - cameraPosition).normalized; // 返回从相机指向中心的方向
	}

	public void OnHitEnemy(float damage, Enemy.DamageType damageType)
	{
	}

	public Settings GetSettings()
	{
		return null;
	}

	public bool NeedZoom()
	{
		return false;
	}

	public void OnFireCannonBall(CannonBall cannonBall)
	{
	}
}
